home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / prog_c / cuj0696.zip / DWYER.ZIP / QFLOAT / DIVN.ASM < prev    next >
Assembly Source File  |  1996-02-24  |  6KB  |  429 lines

  1. ;    Static Name Aliases
  2. ;
  3.     TITLE   divm
  4.  
  5. include qhead.asm
  6. extrn    _mulm:proc
  7. extrn    mdnorm:proc
  8.  
  9. _DATA    SEGMENT
  10. ;extrn    SC:word
  11. B    DW    0
  12. count    DW    0
  13. quot    DW    NQ+2 DUP (?)
  14. _square    DW    NQ+2 DUP (?)
  15. _ans    DW    NQ+2 DUP (?)
  16. _DATA    ENDS
  17.  
  18. _TEXT      SEGMENT
  19.  
  20.  
  21. ; Macro to accumulate twice the partial product
  22. z2mul    MACRO    a,b
  23. ao = 6 + 2*a
  24. bo = 6 + 2*b
  25. co = 8 + 2*a + 2*b
  26. do = 6 + 2*a + 2*b
  27. eo = 4 + 2*a + 2*b
  28.     mov    ax, word ptr [di]+ao
  29.     mul    word ptr [si]+bo
  30.     xor    cx,cx
  31.     sal    ax,1
  32.     rcl    dx,1
  33.     rcl    cx,1
  34.     add    word ptr [bx]+co,ax
  35.     adc    word ptr [bx]+do,dx
  36.     adc    word ptr [bx]+eo,cx
  37.     ENDM
  38.  
  39.  
  40.  
  41.  
  42. extrn    _shdn1:PROC
  43. extrn    _shup1:PROC
  44. extrn    _normlz:PROC
  45. ;
  46. ; Floating point divide
  47. ; @stack into @stack+1
  48. ;
  49. ;
  50. ; The program makes use of 80286 16-bit unsigned
  51. ; MUL and DIV instructions.
  52. ; -Copyright 1988 by Stephen L. Moshier
  53.  
  54.  
  55. ; zdiv( source, dest )
  56. ; dest = numerator
  57.     PUBLIC _divm
  58. _divm    PROC    NEAR
  59.     push    bp
  60.     mov    bp,sp
  61.     push    si
  62.     push    di
  63.     push    bx
  64.     push    cx
  65.     push    es
  66.  
  67.     push    ds
  68.     pop    es
  69.  
  70.  
  71.  
  72.     mov    si, word ptr [bp]+4    ;source, denominator
  73.     mov    di,si
  74.     add    si,8
  75.  
  76. ; Test if the low order denominator is zero.
  77.     lodsw
  78.     or    ax,ax
  79.     je    tiszer
  80.     jmp    nzero
  81.  
  82. tiszer:
  83.     mov    cx,OMG-2
  84. $iszer:
  85.     lodsw
  86.     or    ax,ax
  87.     jne    nnzero
  88.     loop    $iszer
  89.  
  90.     jmp    short yzer
  91.  
  92.  
  93. nnzero:
  94.     jmp    nzero
  95.  
  96.  
  97. yzer:
  98. ; Denominator only has one word of significant bits.
  99. ; Do a single precision divide.
  100.  
  101.     xor    bx,bx
  102.     mov    dx, word ptr [di]+6    ; denominator value
  103. ; get numerator and shift down 1
  104.     mov    si, word ptr [bp]+6    ;numerator
  105.     add    si,4
  106.     lea    di, quot+4
  107.     mov    cx, OMG
  108.     clc
  109. $gnum:
  110.     lodsw
  111.     rcr    ax,1
  112.     stosw
  113.     loop    $gnum
  114.  
  115.     mov    ax,bx
  116.     rcr    ax,1
  117.     stosw
  118.  
  119.     xor    ax,ax
  120.     stosw
  121.  
  122.     lea    si, quot+6        ; numerator
  123.     lea    di,_ans+6
  124.     mov    cx,dx            ;denominator
  125.  
  126.     lodsw
  127.     mov    dx,ax
  128.     lodsw
  129.     div    cx
  130.     stosw
  131.  
  132. REPT OMG-1
  133.     lodsw
  134.     div    cx
  135.     stosw
  136. ENDM
  137.  
  138.     mov    di, word ptr [bp]+6    ; answer
  139.     sub    word ptr [di]+2,1
  140. ; This is the exact quotient since the low order denominator is zero.
  141.     jmp    divfin
  142.  
  143.  
  144. nzero:
  145.  
  146.  
  147.     mov    si,di    ;get denominator pointer
  148.  
  149. ; clear temp area
  150.     lea    di,quot
  151.     mov    cx,NQ+2
  152.     xor    ax,ax
  153.     rep    stosw
  154.  
  155.     mov    cx, word ptr [si]+6    ; denominator value
  156.  
  157. ; divide numerator = 1 by most significant word of denominator
  158. ; compute quotient 1/B to 2 word precision
  159.     lea    di,quot+6    ; significand of quotient
  160.     mov    dx,04000H    ; 1.0
  161.  
  162. REPT 2
  163.     xor    ax,ax
  164.     div    cx
  165.     stosw
  166. ENDM
  167.  
  168. ; Calculate double precision quotient using Taylor series
  169.  
  170. ; clear out temporary storage
  171.     xor    ax,ax
  172.     lea    di,_square
  173.     mov    cx,2*NQ+4
  174.     rep    stosw
  175.  
  176. ; square the quotient
  177.     lea    di,quot
  178.     mov    si,di
  179.     lea    bx,_square
  180.     z2mul    0,1
  181.     zmul    1,1
  182.     zmul    0,0
  183.  
  184. ; multiply squared quotient by low order denominator
  185.     mov    si, word ptr [bp]+4
  186.     lea    di,_square
  187.     lea    bx,_ans
  188. ;        di si
  189.     zmul    2,1
  190.     zmul    1,1
  191.     zmul    0,1
  192. ; shift up 2
  193.     sal    word ptr [bx]+10,1
  194.     rcl    word ptr [bx]+8,1
  195.     rcl    word ptr [bx]+6,1
  196.     sal    word ptr [bx]+10,1
  197.     rcl    word ptr [bx]+8,1
  198.     rcl    word ptr [bx]+6,1
  199.  
  200. ; subtract from quotient
  201.     lea    di,quot
  202.     lea    si,_ans
  203.     mov    ax, word ptr [si]+8
  204.     sub    word ptr [di]+8,ax
  205.     mov    ax, word ptr [si]+6
  206.     sbb    word ptr [di]+6,ax
  207.  
  208. ; do first Newton-Raphson iteration to four word precision
  209. prec = 4
  210. ;    mov    count,3
  211. ;newtlup:
  212.  
  213. ; Loop is done by in-line code with increasing
  214. ; arithmetic precision each iteration.
  215.  
  216. ; Start of Newton-Raphson iterations.
  217. rept NQDIV
  218.  
  219. ; limit precision to maximum available
  220. if prec gt OMG-1
  221. prec = OMG-1
  222. endif
  223.  
  224. ; clear out accumulators
  225.     lea    di,_square
  226.     mov    cx,2*NQ+4
  227.     xor    ax,ax
  228.     rep    stosw
  229.  
  230. ; Form the square of the approximate quotient
  231.  
  232.     lea    si,quot
  233.     mov    di,si
  234.     lea    bx,_square
  235.  
  236.  
  237. hh = prec
  238.  
  239. rept prec
  240. g = 0
  241. h = hh
  242. rept (hh+1)/2
  243. if g LE OMG-1
  244. if h LE OMG-1
  245.     z2mul    g,h
  246. endif
  247. endif
  248. g = g+1
  249. h = h-1
  250. endm
  251.  
  252. if g EQ h
  253.     xor    cx,cx
  254.     zmul    g,g
  255. endif
  256.  
  257. hh = hh-1
  258.  
  259. endm
  260.     xor    cx,cx
  261.     zmul    0,0
  262.  
  263.  
  264. ; multiply the square of the quotient by the denominator
  265.  
  266.     mov    si, word ptr [bp]+4    ;source, denominator
  267.     lea    di,_square
  268.     lea    bx,_ans
  269.  
  270. hh = prec
  271.  
  272. rept prec
  273. g = 0
  274. h = hh
  275. rept (hh+1)/2
  276. if g LE OMG-1
  277. if h LE OMG-2
  278.     zmul    g,h
  279. endif
  280. endif
  281. if h LE OMG-1
  282. if g LE OMG-2
  283.     zmul    h,g
  284. endif
  285. endif
  286. g = g+1
  287. h = h-1
  288. endm
  289.  
  290. if g EQ h
  291.     zmul    g,g
  292. endif
  293.  
  294. hh = hh-1
  295.  
  296. endm
  297.     zmul    0,0
  298.  
  299.  
  300. ; shift the product up 1 bit
  301.  
  302.     lea    bx,_ans
  303.  
  304. h = 2*prec+8
  305.     sal    word ptr [bx]+h,1
  306.  
  307. rept prec+2
  308. h = h-2
  309.     rcl    word ptr [bx]+h,1
  310. endm
  311.  
  312. ; subtract quot - ans
  313.  
  314. i = 2*prec+8
  315.     std
  316.     lea    si,_ans+i
  317.     lea    di,quot
  318.  
  319.     lodsw
  320.     sub    word ptr [di]+i,ax
  321.  
  322. rept prec+2
  323. i=i-2
  324.     lodsw
  325.     sbb    word ptr [di]+i,ax
  326. endm
  327.     cld
  328.  
  329. ; shift result up 1 bit
  330.  
  331.     lea    bx,quot
  332.  
  333. h = 2*prec+8
  334.     sal    word ptr [bx]+h,1
  335.  
  336. rept prec+2
  337. h = h-2
  338.     rcl    word ptr [bx]+h,1
  339. endm
  340.  
  341. ; increase the arithmetic precision for next loop
  342. prec = prec+prec
  343.  
  344. ; end of Newton-Raphson iteration loop
  345. endm
  346.  
  347. ;    sub    count,1
  348. ;    je    divdon
  349. ;    jmp    newtlup
  350.  
  351. divdon:
  352.     cld
  353.  
  354. ; multiply 1/x by the numerator
  355.  
  356. ; temp area for the product
  357.     lea    bx, _ans
  358. ; clear the temp area
  359.     xor    ax,ax
  360.     mov    di,bx
  361.     mov    cx,NQ+2
  362.     rep    stosw
  363.  
  364.     lea    si,quot
  365. ;    mov    si,WORD PTR [bp+4]    ;source
  366.     mov    di,WORD PTR [bp+6]    ;dest
  367.  
  368.     xor    cx,cx    ; for adc 0
  369.  
  370. hh = OMG-1
  371.  
  372. rept OMG-1
  373.  
  374. g = 0
  375. h = hh
  376. rept (hh+1)/2
  377. if g LE OMG-2
  378. if h LE OMG-1
  379.     zmul    g,h
  380. endif
  381. endif
  382. if h LE OMG-2
  383. if g LE OMG-1
  384.     zmul    h,g
  385. endif
  386. endif
  387. g = g+1
  388. h = h-1
  389. endm
  390.  
  391. if g EQ h
  392.     zmul    g,g
  393. endif
  394.  
  395. hh = hh-1
  396.  
  397. endm
  398.  
  399.     zmul    0,0
  400.  
  401.  
  402.  
  403. divfin:
  404.  
  405.  
  406. ; normalize
  407.     mov    di, word ptr [bp]+6
  408.     lea    bx, _ans
  409.     call    mdnorm
  410.  
  411. ; move out the answer
  412.     lea    si, _ans+4
  413.     add    di,4
  414.     mov    cx,OMG
  415.     rep    movsw
  416.  
  417.     pop    es
  418.     pop    cx
  419.     pop    bx
  420.     pop    di
  421.     pop    si
  422.     pop    bp
  423.     ret    
  424. _divm    ENDP
  425.  
  426.  
  427. _TEXT    ENDS
  428. END
  429.